-- $LastChangedDate: 2007-06-01 02:52:33 +0200 (Fri, 01 Jun 2007) $
-- $LastChangedRevision: 149 $
-- $LastchangedBy$

-- packages de ada
WITH Ada.Text_Io;
USE Ada.Text_Io;

-- packages del gimnasio
WITH Tiposprotegidos.Log;
USE Tiposprotegidos.Log;
WITH Tareas.Cliente;
USE Tareas.Cliente;

PACKAGE BODY Tareas.Teclado IS

   FUNCTION More_Tasks_Allowed RETURN Boolean IS
   BEGIN
      IF (Log_Read(Monitor_Cantidad) + Log_Read(Cliente_Cantidad)
            + Log_Read(Aparato_Cantidad) + Log_Read(Medico_Cantidad) + 1) <= Maxtasks THEN
         RETURN True;
      ELSE
         Put_Line("More_tasks_allowed: Se ha alcanzado el numero maximo de tareas permitidas: "&Integer'Image(Maxtasks));
         RETURN False;
      END IF;
   END More_Tasks_Allowed;

   TASK BODY Teclado IS
      Salir : Boolean    := False;
      C     : Character;
      M     : MonitorPtr;
      A     : AparatoPtr;
      Me    : MedicoPtr;
      Cl    : ClientePtr;
      -- eventos posibles de teclado
      Final         : CONSTANT Character := 'q';
      Pausa         : CONSTANT Character := 'p';
      Debugging     : CONSTANT Character := 'd';
      AddMonitor    : CONSTANT Character := 'm';
      AddAparato    : CONSTANT Character := 'a';
      AddMedico     : CONSTANT Character := 'e';
      Add1Cliente   : CONSTANT Character := '1';
      Add10Clientes : CONSTANT Character := '2';
      Add50Clientes : CONSTANT Character := '3';
   BEGIN
      DELAY T_Read_Keyboard;
      WHILE NOT Salir LOOP

         Get_Immediate(C);
         CASE C IS
            WHEN Final =>
               -- indicar a los clientes que el gimnasio va a cerrar
               Term_Signal:= True;

               -- mientras no todos los clientes hayan terminado
               WHILE Log_Read(Cliente_Vete_A_Casa) + Log_Read(Cliente_Entreno_Completo) + Log_Read(Cliente_Muerto) /= Log_Read(Cliente_Cantidad) LOOP
                  DELAY T_Entreno_Normal;
               END LOOP;

               -- indicamos al gestor de monitores que termine
               Gmon.Acabar;

               -- indicamos al gestor de aparatos que termine
               Gapar.Acabar;

               -- indicar al gestor de medicos que termine
               Gmed.Acabar;

               -- indicar al servicio de seguimiento que termine
               Sseg.Acabar;

               -- indicar a la tarea que imprime en consola que termine
               Pantalla.Acabar;

               Salir:= True;
               Print_Term("Teclado: Van a cerrar el gimnasio");
            WHEN Pausa =>
               Put_Line("Pulsa " & Pausa &" para mostrar/no mostrar informacion en pantalla");
               IF Pause_Signal THEN
                  Pause_Signal := False;
               ELSE
                  Pause_Signal:= True;
               END IF;
            WHEN AddMonitor =>
               IF More_Tasks_Allowed THEN
                  M := NEW Monitor(Gmon, Gmed, Sseg);
               END IF;
            WHEN Debugging =>
               Put_Line("Pulsa " & Debugging &" para mostrar/no mostrar informacion de debug");
               IF Debug THEN
                  Debug := False;
               ELSE
                  Debug:= True;
               END IF;
            WHEN AddAparato =>
               IF More_Tasks_Allowed THEN
                  A := NEW Aparato(Gapar, Gmon, Sseg);
               END IF;
            WHEN AddMedico =>
               IF More_Tasks_Allowed THEN
                  Me := NEW Medico(Gmed);
               END IF;
            WHEN Add1Cliente =>
               IF More_Tasks_Allowed THEN
                  Cl := NEW Tareas.Cliente.Cliente(Crear_Cliente, Gmon, Gapar);
               END IF;
            WHEN Add10Clientes =>
               FOR I IN 1..10 LOOP
                  IF More_Tasks_Allowed THEN
                     Cl := NEW Tareas.Cliente.Cliente(Crear_Cliente, Gmon, Gapar);
                  ELSE
                     EXIT;
                  END IF;
               END LOOP;
            WHEN Add50Clientes =>
               FOR I IN 1..50 LOOP
                  IF More_Tasks_Allowed THEN
                     Cl := NEW Tareas.Cliente.Cliente(Crear_Cliente, Gmon, Gapar);
                  ELSE
                     EXIT;
                  END IF;
               END LOOP;
            WHEN OTHERS =>
               NULL;
         END CASE;

         DELAY T_Read_Keyboard;
      END LOOP;
   EXCEPTION
      WHEN Ocurrencia : OTHERS =>
         Put_Line ("Teclado: "&Ada.Exceptions.Exception_Information (Ocurrencia));
   END Teclado;

END Tareas.Teclado;
